package shark.picture.controller;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.poi.util.IOUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import shark.picture.common.BaseResponse;
import shark.picture.common.ResultUtils;
import shark.picture.data.entity.ElecExceptionPolicy;
import shark.picture.data.entity.ElecExceptionRecords;
import shark.picture.exception.ErrorCode;
import shark.picture.exception.ThrowUtils;
import shark.picture.service.ElecExceptionPolicyService;
import shark.picture.service.ElecExceptionRecordsService;
import shark.picture.service.UtilsService;
import shark.picture.utils.aes.AesUtils;
import shark.picture.utils.sm4.SM4Utils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author jianxin.wei
 * @description 测试和各种小工具类
 * @date 2025/2/17 15:38
 */
@RequestMapping("utils")
@RestController
@Slf4j
public class UtilsController {

    @Resource
    private ElecExceptionRecordsService elecExceptionRecordsService;
    @Resource
    private ElecExceptionPolicyService elecExceptionPolicyService;
    @Resource
    private UtilsService utilsService;
    private static final String HEXSTRING = "0123456789ABCDEF";

    static {
        // 在静态代码块中设置，确保全局生效
        IOUtils.setByteArrayMaxOverride(300000000);
    }
    @PostMapping("fillTemplate")
    @ApiOperation(value = "替换文件")
    public BaseResponse<?> fillTemplate(@RequestBody JSONObject param){
        return utilsService.fillTemplate(param);
    }

    @PostMapping("/uploadTemplate")
    @ApiOperation(value = "上传替换模板")
    public BaseResponse<JSONObject> uploadTemplate(@RequestBody MultipartFile file) {
        return utilsService.uploadTemplate(file);
    }

    @PostMapping("/stringToHex")
    @ApiOperation(value = "字符串转哈希")
    public  String stringToHex(@RequestBody JSONObject param)  {
        String str = param.getStr("str");
        // 根据默认编码获取字节数组
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        // 将字节数组中每个字节拆解成2位16进制整数
        for (byte aByte : bytes) {
            sb.append(HEXSTRING.charAt((aByte & 0xf0) >> 4));
            sb.append(HEXSTRING.charAt((aByte & 0x0f)));
        }
        return sb.toString();
    }


    @PostMapping("/hexToString")
    @ApiOperation(value = "哈希转字符串")
    public  String hexToString(@RequestBody JSONObject param) {
        String bytes = param.getStr("bytes");
        ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
        // 将每2位16进制整数组装成一个字节
        for (int i = 0; i < bytes.length(); i += 2)
            baos.write((HEXSTRING.indexOf(bytes.charAt(i)) << 4 | HEXSTRING.indexOf(bytes.charAt(i + 1))));
        return new String(baos.toByteArray(), StandardCharsets.UTF_8);
    }

    /**
     * dx信息Sm4加密
     */
    @PostMapping("/sm4Encrypt")
    @ApiOperation(value = "加密SM4")
    public BaseResponse<String> sm4Encrypt(@RequestBody JSONObject params) {
        String str = params.getStr("str");
        return ResultUtils.success(SM4Utils.encrypt(str));
    }

    @ApiOperation(value = "图片base64转图片")
    @PostMapping("base64ToImage")
    public void base64ToImage(@RequestBody JSONObject jsonObject, HttpServletResponse response) throws IOException {
        utilsService.base64ToImage(jsonObject,response);
    }

    @ApiOperation(value = "图片转base64")
    @PostMapping("ImageToBase64")
    public BaseResponse<?> ImageToBase64(@RequestParam("file") MultipartFile file) throws IOException {
        return utilsService.imageToBase64(file);
    }


    /**
     * dx信息Sm4解密
     */
    @PostMapping("/sm4Decrypt")
    @ApiOperation(value = "解密SM4")
    public BaseResponse<String> sm4Decrypt(@RequestBody JSONObject params) {
        String str = params.getStr("str");
        String decrypt = SM4Utils.decrypt(str);
        ThrowUtils.throwIf(decrypt == null, ErrorCode.PARAMS_ERROR, "解密失败");
        return ResultUtils.success(decrypt);
    }

    @PostMapping("aesEncrypt")
    @ApiOperation(value = "加密AES")
    public BaseResponse<String> aesEncrypt(@RequestBody JSONObject params) {
        String str = params.getStr("str");
        String encrypt;
        try {
            encrypt = AesUtils.encrypt(str);
        } catch (Exception e) {
            log.info("加密失败:", e);
            return ResultUtils.success(ErrorCode.PARAMS_ERROR.getMessage());
        }
        return ResultUtils.success(encrypt);
    }

    @PostMapping("aesDesEn")
    @ApiOperation(value = "解密AES")
    public BaseResponse<String> aesDesEn(@RequestBody JSONObject params) {
        String str = params.getStr("str");
        String decrypt;
        try {
            decrypt = AesUtils.desEncrypt(str);
        }catch (Exception e){
            log.info("解密失败",e);
            return ResultUtils.success(ErrorCode.PARAMS_ERROR.getMessage());
        }
        return ResultUtils.success(decrypt);
    }

    /**
     * 每月爱国网异常数据处理-步骤1
     */
    // todo 每次使用之前记得修改 yml中的 mysql配置
    @PostMapping("/importExceptions")
    @ApiOperation(value = "爱国网异常数据录入")
    public BaseResponse<String> importExceptions(@RequestBody MultipartFile file) throws IOException {
        System.out.println("开始导入");
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<ElecExceptionRecords> list = new ArrayList<>();
        String yyyyMM = Objects.requireNonNull(file.getOriginalFilename()).substring(6, 12);
        List<List<Object>> read = reader.read();
        for (int i = 1; i < read.size(); i++) {
            ElecExceptionRecords entity = new ElecExceptionRecords();
            entity.setPolicyName(getData(reader, 2, i));
            entity.setConsNo(getData(reader, 3, i));
            entity.setConsName(getData(reader, 4, i));
            entity.setElecAddr(getData(reader, 5, i));
            entity.setOrgNo(getData(reader, 6, i));
            entity.setOrgName(getData(reader, 7, i));
            String consType = getData(reader, 8, i);
            entity.setConsType("高压".equals(consType) ? "01" : "低压非居民".equals(consType) ? "02" :
                    "低压居民".equals(consType) ? "03" : "04");
            entity.setBillDate(getData(reader, 9, i));
            entity.setBillDate(yyyyMM);
            entity.setVoltageLevel(getData(reader, 10, i) == null ? null : Long.valueOf(getData(reader, 10, i)));
            entity.setPlanNo(getData(reader, 11, i));
            entity.setCalculateNo(getData(reader, 12, i));
            entity.setMeterNo(getData(reader, 13, i));
            entity.setExceptionType(getData(reader, 14, i) == null ? null : Long.valueOf(getData(reader, 14, i)));
            entity.setCreateTime(reader.readCellValue(15, i) != null ? (Date) reader.readCellValue(15, i) : null);
            entity.setCreateDate(reader.readCellValue(15, i) != null ? (Date) reader.readCellValue(15, i) : null);
            entity.setCalculateTime(getData(reader, 16, i));
            entity.setHandleResult(getData(reader, 17, i) == null ? null : Long.valueOf(getData(reader, 17, i)));
            entity.setHandleTime(reader.readCellValue(18, i) != null ? (Date) reader.readCellValue(18, i) : null);
            list.add(entity);
        }
        elecExceptionRecordsService.saveBatch(list);
        return ResultUtils.success("导入成功");
    }

    @PostMapping("testSend")
    public BaseResponse<String> testSend(@RequestBody JSONObject param) {
//        HttpRequest.post("http://localhost:8001/elecAnalyse/elecForeWarn/uploadTemplate").form("file", file.getResource()).execute().body();

        HttpResponse response = HttpRequest.post("http://localhost:8001/elecAnalyse/elecForeWarn/generateReports").execute();

        return ResultUtils.success(HttpUtil.post("http://localhost:8001/elecAnalyse/elecForeWarn/generateReports", JSONUtil.toJsonStr(param)));
    }
    @PostMapping("testSend1")
    public BaseResponse<String> testSend1(@RequestParam("file") MultipartFile file){
//        HttpRequest.post("http://localhost:8001/elecAnalyse/elecForeWarn/uploadTemplate").form("file", file.getResource()).execute().body();
        try {
            // 构建文件上传请求
            return ResultUtils.success(HttpRequest.post("http://localhost:8001/elecAnalyse/elecForeWarn/uploadTemplate")
                    // 添加文件参数（关键：通过 byte[] + filename 传递）
                    .form("file", file.getBytes(), file.getOriginalFilename())
                    // 添加其他参数
//                    .form("param", JSONObject.toJSONString(param))
                    .execute()
                    .body());
        } catch (IOException e) {
            throw new RuntimeException("文件读取失败", e);
        }
    }

    /**
     * 执行完上一步之后执行这步生成id
     */
    @PostMapping("/getPolicyMap")
    @ApiOperation(value = "生产异常数据的POLICY_ID")
    public BaseResponse<String> getPolicyMap() {
        System.out.println("开始生成policy_id");
        HashMap<String, Object> datas = checkPolicyMapData();
        //新增策略
        List<ElecExceptionPolicy> addList = (List<ElecExceptionPolicy>) datas.get("addList");
        if (!addList.isEmpty()) {
            addPolicyMap(addList);
        }
        //修改策略
        HashMap<String, String> updateMap = (HashMap<String, String>) datas.get("updateMap");
        if (!updateMap.isEmpty()) {
            updatePolicyMap(updateMap);
        }
        return ResultUtils.success("生成policy_id成功");
    }

    @PostMapping("/uploadPhoto")
    @ApiOperation("上传图片")
    public BaseResponse<String> uploadPhoto(String object , @RequestPart("file") MultipartFile file) {
        // 构建文件上传请求
        System.out.println(1);
        return null;
    }

    // 在第一个图片的固定位置叠加第二张图片
    @PostMapping("/modifyImage")
    @ApiOperation("修改图片")
    public BaseResponse<String> modifyImage(@RequestParam("file1") MultipartFile file1 , @RequestParam("file2") MultipartFile file2) {
        //创建文档
        PDDocument pdf = new PDDocument();
        try {
            PDPage page = new PDPage(PDRectangle.A4);
        } catch (Exception e) {

        }

        System.out.println(1);
        return null;
    }

    private HashMap<String, Object> checkPolicyMapData() {
        HashMap<String, String> queryPolicyMap = new HashMap<>();
        for (ElecExceptionPolicy policy : elecExceptionPolicyService.list()) {
            queryPolicyMap.put(policy.getPolicyName(), policy.getId().toString());
        }
        HashMap<String, Object> resultMap = new HashMap<>();
        List<ElecExceptionRecords> list = elecExceptionRecordsService.list();
        List<ElecExceptionPolicy> addList = new ArrayList<>();
        HashMap<String, String> updateMap = new HashMap<>();
        list.forEach(item -> {
            String policyName = item.getPolicyName();
            String policyId = String.valueOf(item.getPolicyId());
            if (StringUtils.isBlank(policyName)) {
                return;
            }
            if (StringUtils.isBlank(queryPolicyMap.get(policyName))) {
                ElecExceptionPolicy policy = new ElecExceptionPolicy();
                policy.setPolicyName(policyName);
                addList.add(policy);
                updateMap.put(policyName, queryPolicyMap.get(policyName));
            } else {
                if (!queryPolicyMap.get(policyName).equals(policyId)) {
                    updateMap.put(policyName, queryPolicyMap.get(policyName));
                }
            }
        });
        resultMap.put("addList", addList);
        resultMap.put("updateMap", updateMap);
        return resultMap;

    }

    private void addPolicyMap(List<ElecExceptionPolicy> addList) {
        elecExceptionPolicyService.saveBatch(addList);
        log.info("新增策略数量：{}", addList.size());
    }

    private void updatePolicyMap(HashMap<String, String> updateMap) {
        updateMap.forEach((k, v) -> {
            LambdaUpdateWrapper<ElecExceptionRecords> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ElecExceptionRecords::getPolicyName, k);
            lambdaUpdateWrapper.set(ElecExceptionRecords::getPolicyId, v);
            elecExceptionRecordsService.update(lambdaUpdateWrapper);
        });
    }

    public static String getData(ExcelReader reader, int x, int y) {
        return String.valueOf(reader.readCellValue(x, y));
    }
}
